home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Windows files / Q3WinSDK.exe / QD3DSDK / Samples / ViewerSample / 3DShell.c next >
Encoding:
C/C++ Source or Header  |  1996-12-20  |  23.6 KB  |  827 lines

  1. #include <windows.h>        // required for all Windows applications
  2. #include "resource.h"        // Windows resource IDs
  3. #include "3dshell.h"        // specific to this program
  4.  
  5. #include <stdio.h>
  6. #include "QD3DWinViewer.h"
  7. #include "TestRoutines.h"
  8. #include "QD3DErrors.h"
  9.  
  10. HINSTANCE hInst;              // current instance
  11. HWND gHwnd;                    // main hwnd
  12.  
  13. TQ3ViewerObject        gViewer;
  14.  
  15. COLORREF customColors[16] = { 0L };
  16.  
  17. char szAppName[] = "QuickDraw 3D Viewer Demo";        // The name of this application
  18. char szTitle[]   = "QuickDraw 3D Viewer Demo";        // The title bar text
  19.  
  20. void DoFlagCommand (unsigned long flag);
  21. void CreateNewViewer ();
  22.  
  23. BOOL        OpenModelFile();
  24. void        SaveModelFile ();
  25. TQ3Status    BrowseForPathName(char *inPathName, BOOLEAN fOpen);
  26. void        OurChooseColor ();
  27.  
  28. void ErrorHandler (
  29.     TQ3Error    firstError,
  30.     TQ3Error    lastError,
  31.     long        reference)
  32. {
  33.     char str[255];
  34.  
  35.     sprintf (str, "First Error: %d, Last Error: %d", firstError, lastError);
  36.  
  37.     MessageBox (gHwnd, str, "QD3D error", MB_OK);
  38. }
  39.  
  40. int CALLBACK WinMain(
  41.         HINSTANCE hInstance,
  42.         HINSTANCE hPrevInstance,
  43.         LPSTR lpCmdLine,
  44.         int nCmdShow)
  45. {
  46.  
  47.         MSG msg;
  48.         HANDLE hAccelTable;
  49.         TQ3Status aStatus = kQ3Failure;
  50.  
  51.         if (!InitApplication(hInstance)) 
  52.         {
  53.             return (FALSE);    
  54.         }
  55.  
  56.         if (!InitInstance(hInstance, nCmdShow)) 
  57.         {
  58.             return (FALSE);
  59.         }
  60.  
  61.         Q3Error_Register (ErrorHandler, 0);
  62.  
  63.         hAccelTable = LoadAccelerators (hInstance, MAKEINTRESOURCE(IDR_GENERIC));
  64.         
  65.         if( lpCmdLine != NULL && (strlen (lpCmdLine) > 0))
  66.         {
  67.             HANDLE fileh;
  68.  
  69.             fileh = CreateFile (lpCmdLine, GENERIC_READ, FILE_SHARE_READ, 
  70.                                    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  71.             
  72.             if (fileh != NULL)
  73.                 aStatus = Q3WinViewerUseFile (gViewer, fileh);
  74.         }
  75.     
  76.         Q3WinViewerDraw( gViewer );
  77.  
  78.         while (GetMessage(&msg, NULL, 0, 0)) {
  79.             if (!TranslateAccelerator (gHwnd, hAccelTable, &msg)) {
  80.                 TranslateMessage(&msg);
  81.                 DispatchMessage(&msg);
  82.             }
  83.         }
  84.  
  85.         return (msg.wParam); // Returns the value from PostQuitMessage
  86. }
  87.  
  88.  
  89. BOOL InitApplication(HINSTANCE hInstance)
  90. {
  91.     WNDCLASS  wc;
  92.     ATOM      success;
  93.     
  94.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  95.     wc.lpfnWndProc   = (WNDPROC)WndProc;       
  96.     wc.cbClsExtra    = 0;                      
  97.     wc.cbWndExtra    = 0;                     
  98.     wc.hInstance     = hInstance;             
  99.     wc.hIcon         = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_APP)); 
  100.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  101.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  102.     wc.lpszMenuName  = MAKEINTRESOURCE(IDR_GENERIC); 
  103.     wc.lpszClassName = szAppName;              
  104.     
  105.     success = RegisterClass(&wc);
  106.  
  107.     return success > 0 ? TRUE : FALSE;
  108. }
  109.  
  110. BOOL InitInstance(
  111.         HINSTANCE       hInstance,
  112.         int             nCmdShow)
  113. {
  114. //    HWND containerWindow;
  115.  
  116.     hInst = hInstance; 
  117.     gHwnd =  CreateWindowEx(
  118.         WS_EX_WINDOWEDGE|WS_EX_CLIENTEDGE,    // extended window style
  119.         szAppName,    // pointer to registered class name
  120.         szTitle,    // pointer to window name
  121.         WS_OVERLAPPED | WS_CAPTION |WS_THICKFRAME | WS_SYSMENU,    // window style
  122.         25, 25, 400, 450,      // fixed size windows
  123.         NULL,    // handle to parent or owner window
  124.         NULL,    // handle to menu, or child-window identifier
  125.         hInstance,    // handle to application instance
  126.         NULL     // pointer to window-creation data
  127.     );
  128.  
  129.     if (!gHwnd) 
  130.     {
  131.         return (FALSE);
  132.     }
  133.  
  134.  
  135.     ShowWindow(gHwnd, nCmdShow); 
  136.     UpdateWindow(gHwnd); 
  137.  
  138.     
  139.     
  140. /*    containerWindow = CreateWindowEx (WS_EX_WINDOWEDGE|WS_EX_CLIENTEDGE,
  141.                             kContainerWindowClass,
  142.                             "Quickdraw 3D Viewer Test Window",
  143.                             WS_OVERLAPPED | WS_CAPTION |WS_THICKFRAME | WS_SYSMENU,
  144.                             430, 25, 500, 500,
  145.                             NULL,
  146.                             NULL,
  147.                             hInstance,
  148.                             NULL);
  149.  
  150.     if (containerWindow == NULL)
  151.     {
  152.         MessageBox (gHwnd, "Creating conatiner window failed", "Windows Error", MB_OK);
  153.         return FALSE;
  154.     }
  155.  
  156.     ShowWindow(containerWindow, SW_SHOW); 
  157.     UpdateWindow(containerWindow); */
  158.  
  159.     return( TRUE );
  160. }
  161.  
  162. void DoFlagCommand (unsigned long flag )
  163. {
  164.     unsigned long flags;
  165.     RECT        aRect;
  166.     TQ3Status    status;
  167.  
  168.     if( NULL == gViewer )
  169.         return;
  170.  
  171.     flags = Q3WinViewerGetFlags (gViewer);
  172.  
  173.     if (flags & flag) 
  174.     {
  175.         flags = flags & ~flag;
  176.     }
  177.     else
  178.     {
  179.         flags = flags | flag;
  180.     }
  181.     
  182.     status = Q3WinViewerSetFlags (gViewer, flags);
  183.  
  184.     (void) GetClientRect(gHwnd, (LPRECT)&aRect);
  185.     (void) InvalidateRect(gHwnd, &aRect, FALSE);    
  186.  
  187. }
  188.  
  189. void InitFlagMenu ( void )
  190. {
  191.     HMENU hMenu;
  192.     unsigned long flags;
  193.  
  194.     if( NULL == gViewer )
  195.         return;
  196.  
  197.     flags = Q3WinViewerGetFlags (gViewer);
  198.     hMenu = GetMenu( gHwnd );
  199.  
  200.     if (flags & kQ3ViewerControllerVisible) 
  201.         CheckMenuItem( hMenu, IDM_CONTROLSTRIP, MF_BYCOMMAND | MF_CHECKED );
  202.     else
  203.         CheckMenuItem( hMenu, IDM_CONTROLSTRIP, MF_BYCOMMAND | MF_UNCHECKED );
  204.     
  205.     if (flags & kQ3ViewerButtonCamera) 
  206.         CheckMenuItem( hMenu, IDM_CAMERABUTTON, MF_BYCOMMAND | MF_CHECKED );
  207.     else
  208.         CheckMenuItem( hMenu, IDM_CAMERABUTTON, MF_BYCOMMAND | MF_UNCHECKED );
  209.  
  210.     if (flags & kQ3ViewerButtonTruck) 
  211.         CheckMenuItem( hMenu, IDM_TRUCKBUTTON, MF_BYCOMMAND | MF_CHECKED );
  212.     else
  213.         CheckMenuItem( hMenu, IDM_TRUCKBUTTON, MF_BYCOMMAND | MF_UNCHECKED );
  214.  
  215.     if (flags & kQ3ViewerButtonOrbit) 
  216.         CheckMenuItem( hMenu, IDM_ORBITBUTTON, MF_BYCOMMAND | MF_CHECKED );
  217.     else
  218.         CheckMenuItem( hMenu, IDM_ORBITBUTTON, MF_BYCOMMAND | MF_UNCHECKED );
  219.  
  220.     if (flags & kQ3ViewerButtonDolly) 
  221.         CheckMenuItem( hMenu, IDM_DOLLYBUTTON, MF_BYCOMMAND | MF_CHECKED );
  222.     else
  223.         CheckMenuItem( hMenu, IDM_DOLLYBUTTON, MF_BYCOMMAND | MF_UNCHECKED );
  224.  
  225.     if (flags & kQ3ViewerButtonZoom)
  226.         CheckMenuItem( hMenu, IDM_ZOOMBUTTON, MF_BYCOMMAND | MF_CHECKED );
  227.     else
  228.         CheckMenuItem( hMenu, IDM_ZOOMBUTTON, MF_BYCOMMAND | MF_UNCHECKED );
  229.  
  230.     if (flags & kQ3ViewerButtonReset) 
  231.         CheckMenuItem( hMenu, IDM_RESETBUTTON, MF_BYCOMMAND | MF_CHECKED );
  232.     else
  233.         CheckMenuItem( hMenu, IDM_RESETBUTTON, MF_BYCOMMAND | MF_UNCHECKED );
  234.     
  235.     if (flags & kQ3ViewerShowBadge) 
  236.         CheckMenuItem( hMenu, IDM_BADGE, MF_BYCOMMAND | MF_CHECKED );
  237.     else
  238.         CheckMenuItem( hMenu, IDM_BADGE, MF_BYCOMMAND | MF_UNCHECKED );
  239.  
  240.     if (flags & kQ3ViewerOutputTextMode) 
  241.         CheckMenuItem( hMenu, IDM_TEXTMODE, MF_BYCOMMAND | MF_CHECKED );
  242.     else
  243.         CheckMenuItem( hMenu, IDM_TEXTMODE, MF_BYCOMMAND | MF_UNCHECKED );
  244.  
  245.     if (flags & kQ3ViewerDraggingInOff) 
  246.         CheckMenuItem( hMenu, IDM_DRAGGINGINOFF, MF_BYCOMMAND | MF_CHECKED );
  247.     else
  248.         CheckMenuItem( hMenu, IDM_DRAGGINGINOFF, MF_BYCOMMAND | MF_UNCHECKED );
  249.  
  250.     if (flags & kQ3ViewerActive) 
  251.         CheckMenuItem( hMenu, IDM_ACTIVE, MF_BYCOMMAND | MF_CHECKED );
  252.     else
  253.         CheckMenuItem( hMenu, IDM_ACTIVE, MF_BYCOMMAND | MF_UNCHECKED );
  254.  
  255.  
  256.     flags = GetWindowLong (Q3WinViewerGetWindow (gViewer), GWL_STYLE);
  257.  
  258.     if (flags & WS_BORDER) 
  259.         CheckMenuItem( hMenu, IDM_DRAWFRAME, MF_BYCOMMAND | MF_CHECKED );
  260.     else
  261.         CheckMenuItem( hMenu, IDM_DRAWFRAME, MF_BYCOMMAND | MF_UNCHECKED );
  262.     
  263. }
  264.  
  265. LRESULT CALLBACK WndProc(
  266.                 HWND hWnd,        
  267.                 UINT message,      
  268.                 WPARAM uParam,     
  269.                 LPARAM lParam)   
  270. {
  271.         int wmId, wmEvent;
  272.  
  273.         switch (message) 
  274.         {
  275.             case WM_COMMAND:
  276.  
  277.                 wmId    = LOWORD(uParam);
  278.                 wmEvent = HIWORD(uParam);
  279.  
  280.                 switch (wmId) 
  281.                 {
  282.                     case IDM_ABOUT:
  283.                         DialogBox(hInst,          
  284.                                 MAKEINTRESOURCE(IDD_ABOUTBOX),
  285.                                 hWnd,                 
  286.                                 (DLGPROC)About);
  287.                         break;
  288.                     case IDM_NEW:
  289.                         CreateNewViewer ();
  290.                         break;
  291.                     case IDM_OPEN:
  292.                         (void) OpenModelFile();
  293.                         break;
  294.                     case IDM_SAVEAS:
  295.                         SaveModelFile();
  296.                         break;
  297.  
  298.                     case IDM_EXIT:
  299.                         DestroyWindow (hWnd);
  300.                         break;
  301.  
  302.                     case IDM_UNDO:
  303.                         if (Q3WinViewerUndo (gViewer) == kQ3Failure)
  304.                             MessageBox (gHwnd, "Q3WinViewerUndo failed", "Edit Menu error", MB_OK);
  305.                         else
  306.                             (void) Q3WinViewerDrawContent (gViewer);
  307.                         break;
  308.                     case IDM_CUT:
  309.                         if (Q3WinViewerCut (gViewer) == kQ3Failure)
  310.                             MessageBox (gHwnd, "Q3WinViewerCut failed", "Edit Menu error", MB_OK);
  311.                         break;
  312.                     case IDM_COPY:
  313.                         if (Q3WinViewerCopy (gViewer) == kQ3Failure)
  314.                             MessageBox (gHwnd, "Q3WinViewerCopy failed", "Edit Menu error", MB_OK);
  315.                         break;
  316.                     case IDM_PASTE:
  317.                         if (Q3WinViewerPaste (gViewer) == kQ3Failure)
  318.                             MessageBox (gHwnd, "Q3WinViewerPaste failed", "Edit Menu error", MB_OK);
  319.                         break;
  320.                     case IDM_CLEAR:
  321.                         if (Q3WinViewerClear (gViewer) == kQ3Failure)
  322.                             MessageBox (gHwnd, "Q3WinViewerClear failed", "Edit Menu error", MB_OK);
  323.                         break;
  324.  
  325.                     case IDM_CONTROLSTRIP:
  326.                         DoFlagCommand (kQ3ViewerControllerVisible);
  327.                         break;
  328.  
  329.                     case IDM_CAMERABUTTON:
  330.                         DoFlagCommand (kQ3ViewerButtonCamera);
  331.                         break;
  332.  
  333.                     case IDM_TRUCKBUTTON:
  334.                         DoFlagCommand (kQ3ViewerButtonTruck);
  335.                         break;
  336.  
  337.                     case IDM_ORBITBUTTON:
  338.                         DoFlagCommand (kQ3ViewerButtonOrbit);
  339.                         break;
  340.  
  341.                     case IDM_DOLLYBUTTON:
  342.                         DoFlagCommand (kQ3ViewerButtonDolly);
  343.                         break;
  344.  
  345.                     case IDM_ZOOMBUTTON:
  346.                         DoFlagCommand (kQ3ViewerButtonZoom);
  347.                         break;
  348.  
  349.                     case IDM_RESETBUTTON:
  350.                         DoFlagCommand (kQ3ViewerButtonReset);
  351.                         break;
  352.  
  353.                     case IDM_BADGE:
  354.                         DoFlagCommand (kQ3ViewerShowBadge);
  355.                         break;
  356.  
  357.                     case IDM_TEXTMODE:
  358.                         DoFlagCommand (kQ3ViewerOutputTextMode);
  359.                         break;
  360.  
  361.                     case IDM_DRAWFRAME:
  362.                         {
  363.                             unsigned long flags = GetWindowLong (Q3WinViewerGetWindow (gViewer), GWL_STYLE);
  364.                             
  365.                             SetLastError (0);
  366.                             flags = SetWindowLong (Q3WinViewerGetWindow (gViewer), GWL_STYLE, flags ^ WS_BORDER);
  367.                     
  368.                             if (flags == 0 && (GetLastError() != 0))
  369.                                 MessageBox (gHwnd, "Setting the WS_BORDER flags failed", "Flag menu error", MB_OK);
  370.                         }
  371.                         break;
  372.  
  373.                     case IDM_DRAGGINGINOFF:
  374.                         DoFlagCommand (kQ3ViewerDraggingInOff);
  375.                         break;
  376.  
  377.                     case IDM_ACTIVE:
  378.                         DoFlagCommand (kQ3ViewerActive);
  379.                         break;
  380.  
  381.                     case IDM_TESTSETWINDOW:
  382.  
  383.                         DoSetWindowTest ();
  384.                         break;
  385.  
  386.                     case IDM_TESTMINDIMENSION:
  387.                         DoTestMinDimension ();
  388.                         break;
  389.  
  390.                     case IDM_TESTGETBUTTONRECT:
  391.                         DoTestGetButtonRect ();
  392.                         break;
  393.  
  394.                     case IDM_TESTSETCAMERABUTTON: /*Q3WinViewerSetCurrentButton tests */
  395.                     case IDM_TESTSETTRUCKBUTTON:
  396.                     case IDM_TESTSETROTATEBUTTON:
  397.                     case IDM_TESTSETZOOMBUTTON:
  398.                     case IDM_TESTSETDOLLYBUTTON:
  399.                         DoTestSetCurrentButton (wmId);
  400.                         break;
  401.  
  402.                     case IDM_TESTGETBITMAP:
  403.                         DoTestGetBitmap ();
  404.                         break;
  405.  
  406.                     case IDM_GETSETCOLOR:
  407.                         OurChooseColor ();
  408.                         break;
  409.  
  410.                     case IDM_TESTWRITEDATA:
  411.                         DoTestWriteData ();
  412.                         break;
  413.  
  414.                     default:
  415.                         return (DefWindowProc(hWnd, message, uParam, lParam));
  416.                 }
  417.                 break;
  418.  
  419.             case WM_INITMENU:
  420.                 {
  421.                     unsigned long    state;
  422.                     HMENU            menu;
  423.  
  424.                     InitFlagMenu();
  425.  
  426.                     state = Q3WinViewerGetState (gViewer);
  427.  
  428.                     menu = GetMenu (gHwnd);
  429.                     
  430.                     if (menu == NULL)
  431.                     {
  432.                         MessageBox (gHwnd, "GetMenu failed in WM_INITMENU", "WM_INITMENU error", MB_OK);
  433.                         return 0;
  434.                     }
  435.  
  436.                     if (state & kQ3ViewerHasUndo)
  437.                     {
  438.                         unsigned long actualSize;
  439.                         char *string;
  440.  
  441.                         if (Q3WinViewerGetUndoString (gViewer, NULL, 0, &actualSize) == kQ3False)
  442.                         {
  443.                             MessageBox (gHwnd, "Q3WinViewerGetUndoString failed in WM_INITMENU", "WM_INITMENU error", MB_OK);
  444.                             return 0;
  445.                         }
  446.  
  447.                         string = malloc (actualSize);
  448.  
  449.                         if (string == NULL)
  450.                         {
  451.                             MessageBox (gHwnd, "malloc failed in WM_INITMENU", "WM_INITMENU error", MB_OK);
  452.                             return 0;
  453.                         }
  454.  
  455.                         if (Q3WinViewerGetUndoString (gViewer, string, actualSize, &actualSize) == kQ3False)
  456.                         {
  457.                             MessageBox (gHwnd, "Q3WinViewerGetUndoString failed in WM_INITMENU", "WM_INITMENU error", MB_OK);
  458.                             free (string);
  459.                             return 0;
  460.                         }
  461.  
  462.                         if (ModifyMenu (menu, IDM_UNDO, MF_BYCOMMAND | MF_STRING, IDM_UNDO, string) == FALSE)
  463.                         {
  464.                             MessageBox (gHwnd, "ModifyMenu failed in WM_INITMENU", "WM_INITMENU error", MB_OK);
  465.                             free (string);
  466.                             return 0;
  467.                         }
  468.  
  469.                         EnableMenuItem (menu, IDM_UNDO, MF_BYCOMMAND | MF_ENABLED);
  470.                         
  471.                         free (string);
  472.                     }
  473.                     else
  474.                     {
  475.                         BOOL val = EnableMenuItem (menu, IDM_UNDO, MF_BYCOMMAND |  MF_GRAYED);
  476.                         if (ModifyMenu (menu, IDM_UNDO, MF_BYCOMMAND | MF_STRING, IDM_UNDO, "Undo") == FALSE)
  477.                         {
  478.                             MessageBox (gHwnd, "ModifyMenu failed in WM_INITMENU", "WM_INITMENU error", MB_OK);
  479.                             return 0;
  480.                         }
  481.  
  482.  
  483.  
  484.                     }
  485.                 }
  486.                 break;
  487.  
  488.             case WM_CREATE:
  489.                 {
  490.                 RECT aWinRect;
  491.                 GetClientRect(hWnd, (LPRECT)&aWinRect);
  492.  
  493.             //    InflateRect (&aWinRect, -50, -50);
  494.                 gViewer = Q3WinViewerNew (hWnd, &aWinRect, (unsigned long) kQ3ViewerDefault);
  495.  
  496.                 if( gViewer == NULL )
  497.                     return -1;
  498.                 }
  499.                 break;
  500.  
  501.             case WM_DESTROY:  // message: window being destroyed
  502.                 PostQuitMessage(0);
  503.                 break;
  504.  
  505.             case WM_SIZE:
  506.                 {
  507.                 long width  = LOWORD(lParam);
  508.                 long height  = HIWORD(lParam);
  509.                 RECT rect;
  510.                 
  511.                 rect.top = 0;
  512.                 rect.left = 0;
  513.                 rect.right = width;
  514.                 rect.bottom = height;
  515.  
  516.                 //InflateRect (&rect, -50, -50);
  517.                 Q3WinViewerSetBounds (gViewer, &rect);
  518.                 }
  519.                 break;
  520.  
  521.             case WM_SETFOCUS:
  522.                 SetFocus( Q3WinViewerGetWindow( gViewer ) );
  523.                 break;
  524.  
  525.             case WM_SYSCOLORCHANGE:
  526.                 SendMessage (Q3WinViewerGetWindow (gViewer), WM_SYSCOLORCHANGE, 0 , 0);
  527.                 break;
  528.  
  529.             default:          // Passes it on if unproccessed
  530.                     return (DefWindowProc(hWnd, message, uParam, lParam));
  531.         }
  532.         return (0);
  533. }
  534.  
  535.  
  536. char ExtFilter[] = "QuickDraw 3D Metafiles\0*.3dmf;*.3dm;*.q3d;*.qd3d\0All Files\0*.*\0\0";
  537.  
  538. // put up common dialog; fOpen == TRUE for Open, FALSE for Save As.
  539. BOOL    BrowseForPathName(char *inPathName, BOOLEAN fOpen) 
  540. {
  541.     OPENFILENAME aFileName;
  542.     BOOL     aStatus = TRUE;
  543.  
  544.     inPathName[0] = 0;
  545.     aFileName.lStructSize = sizeof(OPENFILENAME);
  546.     aFileName.hwndOwner = gHwnd;
  547.     aFileName.hInstance = hInst;
  548.     aFileName.lpstrFilter = ExtFilter;
  549.     aFileName.lpstrCustomFilter = NULL; 
  550.     aFileName.nMaxCustFilter = 0L; 
  551.     aFileName.nFilterIndex = 0; 
  552.     aFileName.lpstrFile = inPathName; 
  553.     aFileName.nMaxFile = 255; 
  554.     aFileName.lpstrFileTitle = NULL;    
  555.     aFileName.nMaxFileTitle = 0; 
  556.     aFileName.lpstrInitialDir = NULL;  
  557.     aFileName.lpstrTitle = NULL;    
  558.     aFileName.Flags = OFN_EXPLORER + OFN_LONGNAMES + OFN_PATHMUSTEXIST; 
  559.     if( fOpen )
  560.         aFileName.Flags += OFN_FILEMUSTEXIST;
  561.     aFileName.nFileOffset = 0; 
  562.     aFileName.nFileExtension = 0; 
  563.     aFileName.lpstrDefExt = NULL; 
  564.     aFileName.lCustData = 0; 
  565.     aFileName.lpfnHook = NULL; 
  566.     aFileName.lpTemplateName = NULL; 
  567.     if (fOpen )
  568.         if (GetOpenFileName((LPOPENFILENAME)&aFileName))
  569.             aStatus = TRUE;
  570.         else
  571.             aStatus = FALSE;
  572.     else //saving
  573.         if (GetSaveFileName((LPOPENFILENAME)&aFileName))
  574.             aStatus = TRUE;
  575.         else
  576.             aStatus = FALSE;
  577.  
  578.     return aStatus;
  579. }
  580.  
  581. BOOL    OpenModelFile()
  582. {
  583.     char                *pathName;
  584.     char                pathNameChars[255];
  585.     TQ3Status            aStatus;
  586.     RECT                aWinRect;
  587.     HANDLE                hFile;
  588.  
  589.     pathName = &(pathNameChars[0]);
  590.     if (BrowseForPathName(pathName, TRUE) != kQ3Success)
  591.         return FALSE;
  592.  
  593.     hFile = CreateFile (pathName, GENERIC_READ, FILE_SHARE_READ, 
  594.                                NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  595.  
  596.     if (hFile == NULL)
  597.         MessageBox (gHwnd, "CreateFile failed", "Yikes", MB_OK);
  598.     else
  599.     {
  600.         aStatus = Q3WinViewerUseFile (gViewer, hFile);
  601.         CloseHandle (hFile);
  602.     }
  603.             
  604.  
  605.  
  606.     (void) GetClientRect(gHwnd, (LPRECT)&aWinRect);
  607.     (void) InvalidateRect(gHwnd, &aWinRect, FALSE);    
  608.     return TRUE;
  609. }
  610.  
  611.  
  612. BOOL CenterWindow (HWND hwndChild, HWND hwndParent)
  613. {
  614.         RECT    rChild, rParent;
  615.         int     wChild, hChild, wParent, hParent;
  616.         int     wScreen, hScreen, xNew, yNew;
  617.         HDC     hdc;
  618.  
  619.         // Get the Height and Width of the child window
  620.         GetWindowRect (hwndChild, &rChild);
  621.         wChild = rChild.right - rChild.left;
  622.         hChild = rChild.bottom - rChild.top;
  623.  
  624.         // Get the Height and Width of the parent window
  625.         GetWindowRect (hwndParent, &rParent);
  626.         wParent = rParent.right - rParent.left;
  627.         hParent = rParent.bottom - rParent.top;
  628.  
  629.         // Get the display limits
  630.         hdc = GetDC (hwndChild);
  631.         wScreen = GetDeviceCaps (hdc, HORZRES);
  632.         hScreen = GetDeviceCaps (hdc, VERTRES);
  633.         ReleaseDC (hwndChild, hdc);
  634.  
  635.         // Calculate new X position, then adjust for screen
  636.         xNew = rParent.left + ((wParent - wChild) /2);
  637.         if (xNew < 0) {
  638.                 xNew = 0;
  639.         } else if ((xNew+wChild) > wScreen) {
  640.                 xNew = wScreen - wChild;
  641.         }
  642.  
  643.         // Calculate new Y position, then adjust for screen
  644.         yNew = rParent.top  + ((hParent - hChild) /2);
  645.         if (yNew < 0) {
  646.                 yNew = 0;
  647.         } else if ((yNew+hChild) > hScreen) {
  648.                 yNew = hScreen - hChild;
  649.         }
  650.  
  651.         // Set it, and return
  652.         return SetWindowPos (hwndChild, NULL,
  653.                 xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  654. }
  655.  
  656.  
  657. // About box callback
  658. LRESULT CALLBACK About(
  659.                 HWND hDlg,           // window handle of the dialog box
  660.                 UINT message,        // type of message
  661.                 WPARAM uParam,       // message-specific information
  662.                 LPARAM lParam)
  663. {
  664.         static  HFONT hfontDlg;
  665.         LPSTR   lpVersion;
  666.         DWORD   dwVerInfoSize;
  667.         DWORD   dwVerHnd;
  668.         UINT    uVersionLen;
  669.         WORD    wRootLen;
  670.         BOOL    bRetCode;
  671.         int     i;
  672.         char    szFullPath[256];
  673.         char    szResult[256];
  674.         char    szGetName[256];
  675.  
  676.         switch (message) {
  677.                 case WM_INITDIALOG:  // message: initialize dialog box
  678.                         // Center the dialog over the application window
  679.                         CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
  680.  
  681.                         // Get version information from the application
  682.                         GetModuleFileName (hInst, szFullPath, sizeof(szFullPath));
  683.                         dwVerInfoSize = GetFileVersionInfoSize(szFullPath, &dwVerHnd);
  684.                         if (dwVerInfoSize) {
  685.                                 // If we were able to get the information, process it:
  686.                                 LPSTR   lpstrVffInfo;
  687.                                 HANDLE  hMem;
  688.                                 hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
  689.                                 lpstrVffInfo  = GlobalLock(hMem);
  690.                                 GetFileVersionInfo(szFullPath, dwVerHnd, dwVerInfoSize, lpstrVffInfo);
  691.                                 lstrcpy(szGetName, "\\StringFileInfo\\040904e4\\");
  692.                                 wRootLen = lstrlen(szGetName);
  693.  
  694.                                 // Walk through the dialog items that we want to replace:
  695.                                 for (i = IDC_FILEDESCRIPTION; i <= IDC_LEGALTRADEMARKS; i++) {
  696.                                         GetDlgItemText(hDlg, i, szResult, sizeof(szResult));
  697.                                         szGetName[wRootLen] = (char)0;
  698.                                         lstrcat (szGetName, szResult);
  699.                                         uVersionLen   = 0;
  700.                                         lpVersion     = NULL;
  701.                                         bRetCode      =  VerQueryValue((LPVOID)lpstrVffInfo,
  702.                                                 (LPSTR)szGetName,
  703.                                                 (LPVOID)&lpVersion,
  704.                                                 (LPDWORD)&uVersionLen); // For MIPS strictness
  705.  
  706.                                         if ( bRetCode && uVersionLen && lpVersion) {
  707.                                                 // Replace dialog item text with version info
  708.                                                 lstrcpy(szResult, lpVersion);
  709.                                                 SetDlgItemText(hDlg, i, szResult);
  710.                                         }
  711.                                 }
  712.  
  713.                                 GlobalUnlock(hMem);
  714.                                 GlobalFree(hMem);
  715.                         } // if (dwVerInfoSize)
  716.                         return (TRUE);
  717.  
  718.                 case WM_COMMAND:                      // message: received a command
  719.                         if (LOWORD(uParam) == IDOK        // "OK" box selected?
  720.                         || LOWORD(uParam) == IDCANCEL) {  // System menu close command?
  721.                                 EndDialog(hDlg, TRUE);        // Exit the dialog
  722.                                 DeleteObject (hfontDlg);
  723.                                 return (TRUE);
  724.                         }
  725.                         break;
  726.         }
  727.         return (FALSE); // Didn't process the message
  728. }
  729.  
  730.  
  731. void CreateNewViewer ()
  732. {
  733.     HWND window =  CreateWindowEx(
  734.             WS_EX_WINDOWEDGE|WS_EX_CLIENTEDGE,    // extended window style
  735.             szAppName,    // pointer to registered class name
  736.             szTitle,    // pointer to window name
  737.             WS_OVERLAPPED | WS_CAPTION |WS_THICKFRAME | WS_SYSMENU,    // window style
  738.             25, 25, 400, 450,      // fixed size windows
  739.             NULL,    // handle to parent or owner window
  740.             NULL,    // handle to menu, or child-window identifier
  741.             hInst,    // handle to application instance
  742.             NULL     // pointer to window-creation data
  743.         );
  744.  
  745.     ShowWindow(window, SW_SHOW); 
  746.     UpdateWindow(window);        
  747.  
  748.  
  749. }
  750.  
  751. void    SaveModelFile(void)
  752. {
  753.     char                *pathName;
  754.     char                pathNameChars[255];
  755.     HANDLE                hFile;
  756.  
  757.     pathName = &(pathNameChars[0]);
  758.     if (BrowseForPathName(pathName, FALSE) != kQ3Success)
  759.         goto ExitSaveModelFile;
  760.  
  761.     
  762.     hFile = CreateFile(
  763.         pathName,    // pointer to name of the file 
  764.         GENERIC_WRITE,    // access (read-write) mode 
  765.         0,    // share mode 
  766.         NULL,    // pointer to security descriptor 
  767.         CREATE_NEW,    // how to create 
  768.         FILE_ATTRIBUTE_NORMAL,    // file attributes 
  769.         NULL     // handle to file with attributes to copy  
  770.     );
  771.  
  772.     if (hFile == NULL)
  773.     {
  774.         MessageBox (gHwnd, "CreateFile failed", "Save As Error", MB_OK);
  775.         return;
  776.     }
  777.  
  778.     if (Q3WinViewerWriteFile (gViewer, hFile) == kQ3Failure)
  779.     {
  780.         MessageBox (gHwnd, "Q3WinViewerWriteFile failec", "Save As Error", MB_OK);
  781.     }
  782.     CloseHandle( hFile );
  783.  
  784. ExitSaveModelFile:
  785.     ;
  786. }
  787.  
  788. void OurChooseColor ()
  789. {
  790.     CHOOSECOLOR cc;
  791.     TQ3ColorARGB color;
  792.     char r, g, b;
  793.  
  794.     memset(&cc,0,sizeof( CHOOSECOLOR ) ); 
  795.     cc.lStructSize = sizeof( CHOOSECOLOR ); 
  796.     cc.hwndOwner = gHwnd; 
  797.     cc.hInstance = hInst; 
  798.     cc.lpCustColors = customColors;
  799.  
  800.     if (Q3WinViewerGetBackgroundColor (gViewer, &color) == kQ3Failure)
  801.     {
  802.         MessageBox (gHwnd, "Q3WinViewerGetBackgroundColor", "Choose color error", MB_OK);
  803.         return;
  804.     }
  805.  
  806.     r = (char ) (color.r * 255.0F) ;
  807.     g = (char) (color.g * 255.0F);
  808.     b = (char) (color.b * 255.0f);
  809.  
  810.     cc.rgbResult = RGB(r,g, b); 
  811.     cc.Flags = CC_RGBINIT; 
  812.  
  813.     if( ChooseColor( &cc ) )
  814.     {
  815.         color.a = 1.0F;
  816.         color.r = (float)GetRValue(cc.rgbResult)/(float)255;
  817.         color.g = (float)GetGValue(cc.rgbResult)/(float)255;
  818.         color.b = (float)GetBValue(cc.rgbResult)/(float)255;
  819.  
  820.         if (Q3WinViewerSetBackgroundColor (gViewer, &color) == kQ3Failure)
  821.             MessageBox (gHwnd, "Q3WinViewerSetBackgroundColor", "Choose color error", MB_OK);
  822.         else
  823.             Q3WinViewerDrawContent (gViewer);
  824.     }
  825.     else
  826.         MessageBox (gHwnd, "ChooseColor failed", "Choose color error", MB_OK);
  827. }